//
//  CYEscape.m
//  CreditAddressBook
//
//  Created by Lee on 15/4/27.
//  Copyright (c) 2015年 Lee. All rights reserved.
//

#import "CYEscape.h"
#import <CommonCrypto/CommonCryptor.h>
#import "GTMBase64.h"

#define gkey            @"Des3-Credit-manage.com-Credit-manage.com-Credit-manage.com"
#define gIv             @"01234567"

#define stringWithChar(a) [NSString stringWithFormat:@"%c", a]

#define CYHEXARRAY @[@"00",@"01",@"02",@"03",@"04",@"05",@"06",@"07",@"08",@"09",@"0A",@"0B",@"0C",@"0D",@"0E",@"0F",@"10",@"11",@"12",@"13",@"14",@"15",@"16",@"17",@"18",@"19",@"1A",@"1B",@"1C",@"1D",@"1E",@"1F",@"20",@"21",@"22",@"23",@"24",@"25",@"26",@"27",@"28",@"29",@"2A",@"2B",@"2C",@"2D",@"2E",@"2F",@"30",@"31",@"32",@"33",@"34",@"35",@"36",@"37",@"38",@"39",@"3A",@"3B",@"3C",@"3D",@"3E",@"3F",@"40",@"41",@"42",@"43",@"44",@"45",@"46",@"47",@"48",@"49",@"4A",@"4B",@"4C",@"4D",@"4E",@"4F",@"50",@"51",@"52",@"53",@"54",@"55",@"56",@"57",@"58",@"59",@"5A",@"5B",@"5C",@"5D",@"5E",@"5F",@"60",@"61",@"62",@"63",@"64",@"65",@"66",@"67",@"68",@"69",@"6A",@"6B",@"6C",@"6D",@"6E",@"6F",@"70",@"71",@"72",@"73",@"74",@"75",@"76",@"77",@"78",@"79",@"7A",@"7B",@"7C",@"7D",@"7E",@"7F",@"80",@"81",@"82",@"83",@"84",@"85",@"86",@"87",@"88",@"89",@"8A",@"8B",@"8C",@"8D",@"8E",@"8F",@"90",@"91",@"92",@"93",@"94",@"95",@"96",@"97",@"98",@"99",@"9A",@"9B",@"9C",@"9D",@"9E",@"9F",@"A0",@"A1",@"A2",@"A3",@"A4",@"A5",@"A6",@"A7",@"A8",@"A9",@"AA",@"AB",@"AC",@"AD",@"AE",@"AF",@"B0",@"B1",@"B2",@"B3",@"B4",@"B5",@"B6",@"B7",@"B8",@"B9",@"BA",@"BB",@"BC",@"BD",@"BE",@"BF",@"C0",@"C1",@"C2",@"C3",@"C4",@"C5",@"C6",@"C7",@"C8",@"C9",@"CA",@"CB",@"CC",@"CD",@"CE",@"CF",@"D0",@"D1",@"D2",@"D3",@"D4",@"D5",@"D6",@"D7",@"D8",@"D9",@"DA",@"DB",@"DC",@"DD",@"DE",@"DF",@"E0",@"E1",@"E2",@"E3",@"E4",@"E5",@"E6",@"E7",@"E8",@"E9",@"EA",@"EB",@"EC",@"ED",@"EE",@"EF",@"F0",@"F1",@"F2",@"F3",@"F4",@"F5",@"F6",@"F7",@"F8",@"F9",@"FA",@"FB",@"FC",@"FD",@"FE",@"FF"]

@interface CYEscape ()


@end

@implementation CYEscape


/**
 *  数据加密
 */
+ (NSString *)escapeWithString:(NSString *)s {
    NSMutableString *sbuf = [NSMutableString stringWithString:@""];
    if (![s isKindOfClass:[NSString class]]) {
        s = [NSString stringWithFormat:@"%@", s];
    }
    NSUInteger len = s.length;
    NSArray *hex = CYHEXARRAY;
    for (int i = 0; i < len; i++) {
        int ch = [s characterAtIndex:i];
        if (ch == ' ') {
//            sbuf.append('+');
            [sbuf appendString:@"+"];
        } else if ('A' <= ch && ch <= 'Z') {
//            sbuf.append((char)ch);
            [sbuf appendString:stringWithChar((char)ch)];
        } else if ('a' <= ch && ch <= 'z') {
//            sbuf.append((char)ch);
            [sbuf appendString:stringWithChar((char)ch)];
        } else if (0 <= ch && ch <= 9) {
//            sbuf.append((char)ch);
            [sbuf appendString:stringWithChar((char)ch)];
        } else if (ch == '-' || ch == '_'
                   || ch == '.' || ch == '!'
                   || ch == '~' || ch == '*'
                   || ch == '\'' || ch == '('
                   || ch == ')') {
//            sbuf.append((char)ch);
            [sbuf appendString:stringWithChar((char)ch)];
        } else if (ch <= 0x007F) {
//            sbuf.append('%');
//            sbuf.append(hex[ch]);
            [sbuf appendString:stringWithChar('%')];
            [sbuf appendString:hex[ch]];
        } else {
//            sbuf.append('%');
//            sbuf.append('u');
//            sbuf.append(hex[(ch >>> 8)]);
//            sbuf.append(hex[(0x00FF & ch)]);
            [sbuf appendString:stringWithChar('%')];
            [sbuf appendString:stringWithChar('u')];
            int a = ch >> 8;
            [sbuf appendString:hex[a]];
            int b = (0x00FF & ch);
            [sbuf appendString:hex[b]];
        }
    }
    return sbuf;
}

// 加密方法
+ (NSString*)encrypt:(NSString*)plainText {
    NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding];
    size_t plainTextBufferSize = [data length];
    const void *vplainText = (const void *)[data bytes];
    
    CCCryptorStatus ccStatus;
    uint8_t *bufferPtr = NULL;
    size_t bufferPtrSize = 0;
    size_t movedBytes = 0;
    
    bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
    bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
    memset((void *)bufferPtr, 0x0, bufferPtrSize);
    
    const void *vkey = (const void *) [gkey UTF8String];
    const void *vinitVec = (const void *) [gIv UTF8String];
    
    ccStatus = CCCrypt(kCCEncrypt,
                       kCCAlgorithm3DES,
                       kCCOptionPKCS7Padding,
                       vkey,
                       kCCKeySize3DES,
                       vinitVec,
                       vplainText,
                       plainTextBufferSize,
                       (void *)bufferPtr,
                       bufferPtrSize,
                       &movedBytes);
    
    NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
    NSString *result = [GTMBase64 stringByEncodingData:myData];
    return result;
}

// 解密方法
+ (NSString*)decrypt:(NSString*)encryptText {
    NSData *encryptData = [GTMBase64 decodeData:[encryptText dataUsingEncoding:NSUTF8StringEncoding]];
    size_t plainTextBufferSize = [encryptData length];
    const void *vplainText = [encryptData bytes];
    
    CCCryptorStatus ccStatus;
    uint8_t *bufferPtr = NULL;
    size_t bufferPtrSize = 0;
    size_t movedBytes = 0;
    
    bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
    bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
    memset((void *)bufferPtr, 0x0, bufferPtrSize);
    
    const void *vkey = (const void *) [gkey UTF8String];
    const void *vinitVec = (const void *) [gIv UTF8String];
    
    ccStatus = CCCrypt(kCCDecrypt,
                       kCCAlgorithm3DES,
                       kCCOptionPKCS7Padding,
                       vkey,
                       kCCKeySize3DES,
                       vinitVec,
                       vplainText,
                       plainTextBufferSize,
                       (void *)bufferPtr,
                       bufferPtrSize,
                       &movedBytes);
    NSString *result = [[NSString alloc]initWithData:[NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes] encoding:NSUTF8StringEncoding];
    
    return result;
}
@end
